package com.chenl.provider.util;

import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class HttpUtils {
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class HttpResult {
        private Integer code;
        private String message;
        private Object data;

        public static HttpResult success() {
            return new HttpResult(0, "success", null);
        }

        public static HttpResult success(Integer code, String message, Object data) {
            HttpResult httpResult = new HttpResult();
            if (code != null) {
                httpResult.setCode(code);
            } else {
                httpResult.setCode(0);
            }
            if (message != null) {
                httpResult.setMessage(message);
            } else {
                httpResult.setMessage("success");
            }
            if (message != null) {
                httpResult.setData(data);
            } else {
                httpResult.setData(null);
            }
            return httpResult;
        }

        public static HttpResult error(String errorMsg) {
            HttpResult result = new HttpResult(1, "error", null);
            if (errorMsg != null) {
                result.setMessage(errorMsg);
            }
            return result;
        }
    }

    /**
     * 发送Post请求
     *
     * @param url          URL
     * @param object       要发送的数据 可为null
     * @param headersMap   请求头  可为null
     * @param restTemplate restTemplate
     * @return
     */
    public static HttpResult PostHttp(String url, Object object, Map<String, String> headersMap, RestTemplate restTemplate, Class<? extends Object> clazz) {//post请求发送对象并添加请求头
        HttpHeaders headers = new HttpHeaders();
        if (headersMap != null && headersMap.get("Content-Type") != null) {
            headers.setContentType(MediaType.parseMediaType(headersMap.get("Content-Type")));
            headersMap.remove("Content-Type");
        } else {
            headers.setContentType(MediaType.APPLICATION_JSON);
        }
        if (headersMap!=null){
            for (Map.Entry<String, String> entry : headersMap.entrySet()) {
                headers.add(entry.getKey(), entry.getValue());
            }
        }
        HttpEntity<String> strEntity = null;
        if (object != null &&! (object instanceof String)){
            strEntity = new HttpEntity<>(JSONObject.toJSONString(object), headers);
        }else {
            strEntity = new HttpEntity<>((String) object, headers);
        }
        ResponseEntity<? extends Object> responseEntity = null;
        responseEntity = restTemplate.exchange(url, HttpMethod.POST, strEntity, clazz);
        if (String.valueOf(responseEntity.getStatusCode().value()).equals("200")) {
            if (responseEntity.getBody() != null) {
                return HttpResult.success(0, "success", responseEntity.getBody());
            }
            return HttpResult.success();
        } else {
            return HttpResult.error(responseEntity.toString());
        }
    }
    /**
     * 发送Post请求携带Body-Xml格式
     *
     * @param url          URL
     * @param xml       要发送的数据 可为null
     * @param headersMap   请求头  可为null
     * @param restTemplate restTemplate
     * @return
     */
    public static HttpResult XmlHttp(String url, String xml, Map<String, String> headersMap, RestTemplate restTemplate) {//post请求发送对象并添加请求头
        HttpHeaders headers = new HttpHeaders();
        if (headersMap != null && headersMap.get("Content-Type") != null) {
            headers.setContentType(MediaType.parseMediaType(headersMap.get("Content-Type")));
        } else {
            headers.setContentType(MediaType.APPLICATION_XML);
        }
        if (headersMap!=null){
            for (Map.Entry<String, String> entry : headersMap.entrySet()) {
                if (!entry.getKey().equalsIgnoreCase("Content-Type")){
                    headers.add(entry.getKey(), entry.getValue());
                }
            }
        }
        HttpEntity<String> strEntity = new HttpEntity<>(xml, headers);
        ResponseEntity<? extends Object> responseEntity = null;
        responseEntity = restTemplate.exchange(url, HttpMethod.POST, strEntity, String.class);
        if (String.valueOf(responseEntity.getStatusCode().value()).equals("200")) {
            if (responseEntity.getBody() != null) {
                return HttpResult.success(0, "success", responseEntity.getBody());
            }
            return HttpResult.success();
        } else {
            return HttpResult.error(responseEntity.toString());
        }
    }
    public static String sendWstXml(String xml,String url){
        String body = cn.hutool.http.HttpRequest.post(url)
                .setFollowRedirects(true)
                .setConnectionTimeout(15000)
                .setReadTimeout(15000)
                .contentType("text/xml;charset=UTF-8")
                .body(xml)
                .executeAsync().body();
        //响应xml 去除没用部分转换map
        String resultXml = body.replace("&lt;", "<").replace("&gt;", ">");
        return resultXml;
    }
    /**
     * 发送Post请求,发送文件
     * @return
     */
    public static HttpResult PostFile(String url, Map<String,Object> reqMap, Map<String, String> headersMap, RestTemplate restTemplate, Class<? extends Object> clazz) throws IOException {//post请求发送对象并添加请求头
        HttpHeaders headers = new HttpHeaders();
        if (headersMap != null && headersMap.get("Content-Type") != null) {
            headers.setContentType(MediaType.parseMediaType(headersMap.get("Content-Type")));
        } else {
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        }
        if (headersMap!=null){
            for (Map.Entry<String, String> entry : headersMap.entrySet()) {
                headers.add(entry.getKey(), entry.getValue());
            }
        }
        MultiValueMap<String, Object> bodyParams = new LinkedMultiValueMap<>();
        for (Map.Entry<String, Object> entry : reqMap.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (key.contains("file")){
                if (value instanceof MultipartFile){
                    MultipartFile file= (MultipartFile) value;
                    Resource resource = new ByteArrayResource(file.getBytes()){
                        @Override
                        public String getFilename() {
                            return file.getOriginalFilename();
                        }
                    };
                    bodyParams.add(key,resource);
                    continue;
                }else if (value instanceof File){
                    File file= (File) value;
                    Resource resource = new FileSystemResource(file);
                    bodyParams.add(key,resource);
                    continue;
                }
            }
            bodyParams.add(key,value);

        }

        HttpEntity<MultiValueMap> strEntity = new HttpEntity<>(bodyParams, headers);
        ResponseEntity<? extends Object> responseEntity = null;
//        Object o;
        try {
//             o = restTemplate.postForObject(url, strEntity, clazz);
            responseEntity = restTemplate.exchange(url,HttpMethod.POST, strEntity, clazz);
        } catch (RestClientException e) {
            return HttpResult.error(e.toString());
        }
        if (String.valueOf(responseEntity.getStatusCode().value()).equals("200")) {
            if (responseEntity.getBody() != null) {
                return HttpResult.success(0, "success", responseEntity);
            }
            return HttpResult.success();
        } else {
            return HttpResult.error(responseEntity.toString());
        }
    }
    public static Map<String, Object> GetHttp(String url, Map<String, String> map, Map<String, String> headersMap) {//get请求带路径参数和请求头
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        if (JSONObject.toJSONString(headersMap).contains("content")) {
            headers.setContentType(MediaType.APPLICATION_JSON);
        }
        if (headersMap != null && headersMap.size() > 0) {
            for (Map.Entry<String, String> entry : headersMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                headers.add(key, value);
            }
        }
        HttpEntity<MultiValueMap> httpEntity = new HttpEntity<>(null, headers);
        if (map.size() > 0) {
            url += "?";
            for (Map.Entry<String, String> stringStringEntry : map.entrySet()) {
                String key = stringStringEntry.getKey();
                String value = stringStringEntry.getValue();
                url += key + "=" + value + "&";
            }
        }
        url = url.substring(0, url.length() - 1);
        log.info("getHttpUrl---:{}", url);
        ResponseEntity<String> forEntity = null;
        Map<String, Object> respMap = new HashMap<>();
        try {
            forEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
        } catch (RestClientException e) {
            respMap.put("exception", e.toString());
            return respMap;
        }
        String body = forEntity.getBody();
        HttpStatus statusCode = forEntity.getStatusCode();
        respMap.put("body", body);
        respMap.put("statusCode", statusCode);
        return respMap;
    }
}